package com.sc.nft.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sc.nft.dao.*;
import com.sc.nft.dto.*;
import com.sc.nft.entity.*;
import com.sc.nft.entity.dto.GasConsumeDTO;
import com.sc.nft.entity.vo.ecology.*;
import com.sc.nft.enums.*;
import com.sc.nft.exception.GlobalException;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@RequiredArgsConstructor
@Service
public class EcologyCastServiceImpl implements EcologyCastService {

    private final EcologyCastConfDao ecologyCastConfDao;
    private final EcologyCastExpendConfDao ecologyCastExpendConfDao;
    private final UserEcologyPointsService userEcologyPointsService;
    private final UserEquityPropsService userEquityPropsService;
    private final StaticDataDao staticDataDao;
    private final UserEcologyCastRecordsDao userEcologyCastRecordsDao;
    private final UserEcologyExpenditureRecordDao userEcologyExpenditureRecordDao;
    private final DigitalCollectionProductInfoDao digitalCollectionProductInfoDao;
    private final ProductStockDao productStockDao;
    private final ProductStockService productStockService;
    private final BoxItemService boxItemService;
    private final BoxProductDao boxProductDao;
    private final DigitalCollectionDao digitalCollectionDao;
    private final UserCollectionService userCollectionService;
    private final UserEcologyHatchRecordsDao userEcologyHatchRecordsDao;
    private final UserEcologyCastRecordsDetailsDao userEcologyCastRecordsDetailsDao;
    private final UserEcologyCastUpperLimitDao userEcologyCastUpperLimitDao;
    private final UserEcologyCastUpperLimitDetailsDao userEcologyCastUpperLimitDetailsDao;
    private final FilterIncomeListDao filterIncomeListDao;
    private final UserEcologyCastUpperLimitService userEcologyCastUpperLimitService;
    private final EcologyHatchConfDao ecologyHatchConfDao;
    private final EcologyCastExchangeConfService ecologyCastExchangeConfService;
    private final EcologyCastWayConfDao ecologyCastWayConfDao;
    private final UserWalletDao userWalletDao;
    private final OrderGasService orderGasService;
    private final UserEcologyPointsWalletService userEcologyPointsWalletService;
    private final EcologyPointsService ecologyPointsService;

    @Override
    public EcologyCastConf getById(Long id) {
        return ecologyCastConfDao.getById(id);
    }

    @Override
    public Page<EcologyCastListVO> list(Integer pageNo, Integer pageSize, Long userCreatorId) {
        return ecologyCastConfDao.getPageEcologyCast(pageNo, pageSize, userCreatorId);
    }

    @Override
    public EcologyCastDetailsVO details(Long ecologyCastConfId, UserInfo user) {
        EcologyCastConf ecologyCastConf = ecologyCastConfDao.getById(ecologyCastConfId);
        Assert.notNull(ecologyCastConf, () -> new GlobalRunTimeException("生态铸造配置不存在"));
        Assert.isTrue(ecologyCastConf.getStatus(), () -> new GlobalRunTimeException("生态铸造配置已下架"));

        EcologyCastDetailsVO ecologyCastDetails = ecologyCastConfDao.getProductDetailsById(ecologyCastConfId);
        Assert.notNull(ecologyCastDetails, () -> new GlobalRunTimeException("生态铸造商品不存在"));

        //生态燃料图片
        String ecologyPointsImage = staticDataDao.getByType("ecology_points_image").getValue();

        ArrayList<EcologyCastWayVO> wayList = Lists.newArrayList();

        //铸造方式明细
        List<EcologyCastWayConf> wayConfList = ecologyCastWayConfDao.getListByEcologyCastConfIdAndStatus(ecologyCastConfId, Boolean.TRUE);
        List<Long> wayConfIdList = wayConfList.stream().map(EcologyCastWayConf::getId).collect(Collectors.toList());
        //销毁明细
        List<EcologyCastExpendConf> list = ecologyCastExpendConfDao.getListByEcologyCastWayConfIdList(wayConfIdList);
        //根据方式分组
        Map<Long, List<EcologyCastExpendConf>> wayCastExpendConfMap = list.stream().collect(Collectors.groupingBy(EcologyCastExpendConf::getEcologyCastWayConfId));


        //是否熔炼了该藏品
        ecologyCastDetails.setIsHatch(userEcologyHatchRecordsDao.getNewCountByStatusAndUserIdAndCollectionId(user.getId(), ecologyCastConf.getCollectionId()) > 0);


        //设置铸造上限
        UserEcologyCastUpperLimit userEcologyCastUpperLimitDetails = userEcologyCastUpperLimitDao.getOneByUserIdAndCollectionId(user.getId(), ecologyCastConf.getCollectionId());
        ecologyCastDetails.setUpperLimit(ObjectUtil.isNull(userEcologyCastUpperLimitDetails) ? 0 : userEcologyCastUpperLimitDetails.getUsableCount());
        ecologyCastDetails.setUserUsableCount(ObjectUtil.isNull(userEcologyCastUpperLimitDetails) ? 0 : userEcologyCastUpperLimitDetails.getUsableCount());

        for (EcologyCastWayConf ecologyCastWayConf : wayConfList) {
            EcologyCastWayVO ecologyCastWayVO = new EcologyCastWayVO();
            ecologyCastWayVO.setWayId(ecologyCastWayConf.getId());
            ecologyCastWayVO.setType(Boolean.FALSE);
            List<EcologyCastExpendConf> ecologyCastExpendConfs = wayCastExpendConfMap.get(ecologyCastWayConf.getId());
            HashSet<Boolean> booleans = new HashSet<>();
            ArrayList<EcologyCastExpendVO> expendList = Lists.newArrayList();
            for (EcologyCastExpendConf ecologyCastExpendConf : ecologyCastExpendConfs) {
                EcologyCastExpendVO ecologyCastExpendVO = BeanUtil.copyProperties(ecologyCastExpendConf, EcologyCastExpendVO.class);
                if (ecologyCastExpendConf.getExpendType() == EcologyExpendType.ECOLOGY_POINTS) {
                    UserEcologyPoints userEcologyPoints = userEcologyPointsService.getOneByUserId(user.getId());
                    ecologyCastExpendVO.setHoldCount(userEcologyPoints.getAmount());
                    ecologyCastExpendVO.setExpendImage(ecologyPointsImage);
                    ecologyCastExpendVO.setExpendCount(ecologyCastExpendConf.getExpendCount());
                    if (userEcologyPoints.getAmount().compareTo(ecologyCastExpendConf.getExpendCount()) > -1) {//用户持有数量大于等于消耗数量
                        booleans.add(Boolean.TRUE);
                    } else {
                        booleans.add(Boolean.FALSE);
                    }
                }

                if (ecologyCastExpendConf.getExpendType() == EcologyExpendType.EQUITY_PROPS) {
                    Integer havingCount = userEquityPropsService.getHavingCountByUserId(ecologyCastExpendConf.getExpendId(), user.getId());
                    ecologyCastExpendVO.setHoldCount(Convert.toBigDecimal(havingCount));
                    ecologyCastExpendVO.setExpendCount(ecologyCastExpendConf.getExpendCount());

                    if (Convert.toBigDecimal(havingCount).compareTo(ecologyCastExpendConf.getExpendCount()) > -1) {//用户持有数量大于等于消耗数量
                        booleans.add(Boolean.TRUE);
                    } else {
                        booleans.add(Boolean.FALSE);
                    }
                }

                if (ecologyCastExpendConf.getExpendType() == EcologyExpendType.ECOLOGY_MARK) {
                    UserEcologyPointsWallet userEcologyPointsWallet = userEcologyPointsWalletService.getOneByUserIdAndPointId(ecologyCastExpendConf.getExpendId(),user.getId());
                    BigDecimal amount = BigDecimal.ZERO;
                    if (Objects.nonNull(userEcologyPointsWallet)) {
                        amount = userEcologyPointsWallet.getAmount();
                    }
                    ecologyCastExpendVO.setHoldCount(amount);
                    ecologyCastExpendVO.setExpendImage(ecologyPointsImage);
                    ecologyCastExpendVO.setExpendCount(ecologyCastExpendConf.getExpendCount());
                    if (amount.compareTo(ecologyCastExpendConf.getExpendCount()) > -1) {//用户持有数量大于等于消耗数量
                        booleans.add(Boolean.TRUE);
                    } else {
                        booleans.add(Boolean.FALSE);
                    }
                }

                expendList.add(ecologyCastExpendVO);
            }
            if (booleans.contains(Boolean.FALSE)) {
                ecologyCastWayVO.setType(Boolean.FALSE);
            } else {
                if (ecologyCastDetails.getUpperLimit() > 0) {
                    ecologyCastWayVO.setType(Boolean.TRUE);
                }
            }
            ecologyCastWayVO.setExpendList(expendList);
            wayList.add(ecologyCastWayVO);
        }
        ecologyCastDetails.setWayList(wayList);
        DigitalCollectionProductInfo productInfo = digitalCollectionProductInfoDao.getById(ecologyCastDetails.getProductId());
        //获取上链费信息
        if (productInfo.getGasConf()) {
            UserWallet userWallet = userWalletDao.getByUserId(user.getId());
            EcologyCastGasVO ecologyCastGas = new EcologyCastGasVO();
            ecologyCastGas.setConsumeType(productInfo.getConsumeType());
            ecologyCastGas.setGasConf(productInfo.getGasConf());
            ecologyCastGas.setConsumeCost(productInfo.getConsumeCost());
            ecologyCastGas.setBalance(Objects.isNull(userWallet)?BigDecimal.ZERO:userWallet.getBalance());
            ecologyCastDetails.setEcologyCastGas(ecologyCastGas);
        }

        ecologyCastDetails.setProductDetailPictureType(productInfo.getProductDetailPictureType());
        ecologyCastDetails.setModelImg(productInfo.getModelImg());
        ecologyCastDetails.setModelDistance(productInfo.getModelDistance());
        ecologyCastDetails.setProductPresentation(productInfo.getEcologyCastPresentation());
        ProductStock productStock = productStockDao.getByProductId(ecologyCastDetails.getProductId());
        ecologyCastDetails.setUsableCount(ObjectUtil.isNull(productStock) ? 0 : productStock.getUsableCount());
        ecologyCastDetails.setProductDetailPicture(productInfo.getProductDetailPicture());
        ecologyCastDetails.setIsLockedPosition(productInfo.getIsLockedPosition());
        ecologyCastDetails.setLockedPositionType(productInfo.getLockedPositionType());
        ecologyCastDetails.setLockedPositionHour(productInfo.getLockedPositionHour());
        ecologyCastDetails.setLockedPositionTime(productInfo.getLockedPositionTime());
        ecologyCastDetails.setLockedPositionDescribe();
        EcologyHatchConf ecologyHatchConf = ecologyHatchConfDao.getOneByCollectionId(ecologyCastConf.getCollectionId());
        ecologyCastDetails.setAddCastCount(ObjectUtil.isNull(ecologyHatchConf) ? 0 : ecologyHatchConf.getAddCastCount());
        Boolean convertibilityCeiling = ecologyCastExchangeConfService.getIsExistByEcologyCastId(ecologyCastConfId);
        // 是否配置了兑换上限
        ecologyCastDetails.setConvertibilityCeiling(convertibilityCeiling);
        if (filterIncomeListDao.checkIsFilterAccount(digitalCollectionDao.getById(ecologyCastConf.getCollectionId()).getUserCreatorId(), user.getId())
                || filterIncomeListDao.checkListIsFilterAccount(Arrays.asList(6L, 7L, 131L, 145L), user.getId())) {
            for (EcologyCastWayVO ecologyCastWayVO : ecologyCastDetails.getWayList()) {
                ecologyCastWayVO.setType(Boolean.TRUE);
            }
            ecologyCastDetails.setUpperLimit(ecologyCastDetails.getUsableCount());
            ecologyCastDetails.setUserUsableCount(ecologyCastDetails.getUsableCount());
            ecologyCastDetails.setUsableCount(ecologyCastDetails.getUsableCount());
            ecologyCastDetails.setIsHatch(Boolean.TRUE);
        }

        return ecologyCastDetails;
    }

    @Override
    public List<EcologyCastWayVO> preExpendDetails(Long id, Integer count, UserInfo user) {
        EcologyCastConf ecologyCastConf = ecologyCastConfDao.getById(id);
        Assert.notNull(ecologyCastConf, () -> new GlobalRunTimeException("生态铸造配置不存在"));
        Assert.isTrue(ecologyCastConf.getStatus(), () -> new GlobalRunTimeException("生态铸造配置已下架"));

        EcologyCastDetailsVO ecologyCastDetails = ecologyCastConfDao.getProductDetailsById(id);
        Assert.notNull(ecologyCastDetails, () -> new GlobalRunTimeException("生态铸造商品不存在"));

        List<EcologyCastWayConf> ecologyCastWayConfList = ecologyCastWayConfDao.getListByEcologyCastConfIdAndStatus(id, Boolean.TRUE);

        List<EcologyCastWayVO> ecologyCastWayVOList = Lists.newArrayList();

        for (EcologyCastWayConf ecologyCastWayConf : ecologyCastWayConfList) {
            EcologyCastWayVO ecologyCastWayVO = new EcologyCastWayVO();
            ecologyCastWayVO.setWayId(ecologyCastWayConf.getId());
            ecologyCastWayVO.setType(Boolean.FALSE);
            ArrayList<EcologyCastExpendVO> expendList = Lists.newArrayList();
            //生态燃料图片
            String ecologyPointsImage = staticDataDao.getByType("ecology_points_image").getValue();
            HashSet<Boolean> booleans = new HashSet<>();
            //销毁明细
            List<EcologyCastExpendConf> list = ecologyCastExpendConfDao.getListByEcologyCastWayConfId(ecologyCastWayConf.getId());
            for (EcologyCastExpendConf ecologyCastExpendConf : list) {
                EcologyCastExpendVO ecologyCastExpendVO = BeanUtil.copyProperties(ecologyCastExpendConf, EcologyCastExpendVO.class);

                if (ecologyCastExpendConf.getExpendType() == EcologyExpendType.ECOLOGY_POINTS) {
                    UserEcologyPoints userEcologyPoints = userEcologyPointsService.getOneByUserId(user.getId());
                    ecologyCastExpendVO.setHoldCount(userEcologyPoints.getAmount());
                    ecologyCastExpendVO.setExpendImage(ecologyPointsImage);
                    ecologyCastExpendVO.setExpendCount(ecologyCastExpendConf.getExpendCount().multiply(Convert.toBigDecimal(count)));
                    if (userEcologyPoints.getAmount().compareTo(new BigDecimal(ecologyCastExpendVO.getExpendCount()).setScale(2, RoundingMode.DOWN)) > -1) {//用户持有数量大于等于消耗数量
                        booleans.add(Boolean.TRUE);
                    } else {
                        booleans.add(Boolean.FALSE);
                    }
                }

                if (ecologyCastExpendConf.getExpendType() == EcologyExpendType.EQUITY_PROPS) {
                    Integer havingCount = userEquityPropsService.getHavingCountByUserId(ecologyCastExpendConf.getExpendId(), user.getId());
                    ecologyCastExpendVO.setHoldCount(Convert.toBigDecimal(havingCount));
                    ecologyCastExpendVO.setExpendCount(ecologyCastExpendConf.getExpendCount().multiply(Convert.toBigDecimal(count)));
                    if (Convert.toBigDecimal(havingCount).compareTo(new BigDecimal(ecologyCastExpendVO.getExpendCount()).setScale(2, RoundingMode.DOWN)) > -1) {//用户持有数量大于等于消耗数量
                        booleans.add(Boolean.TRUE);
                    } else {
                        booleans.add(Boolean.FALSE);
                    }
                }
                if (ecologyCastExpendConf.getExpendType() == EcologyExpendType.ECOLOGY_MARK) {
                    UserEcologyPointsWallet userEcologyPointsWallet = userEcologyPointsWalletService.getOneByUserIdAndPointId(ecologyCastExpendConf.getExpendId(),user.getId());
                    BigDecimal amount = BigDecimal.ZERO;
                    if (Objects.nonNull(userEcologyPointsWallet)) {
                        amount = userEcologyPointsWallet.getAmount();
                    }
                    ecologyCastExpendVO.setHoldCount(amount);
                    ecologyCastExpendVO.setExpendImage(ecologyPointsImage);
                    ecologyCastExpendVO.setExpendCount(ecologyCastExpendConf.getExpendCount());
                    if (amount.compareTo(ecologyCastExpendConf.getExpendCount()) > -1) {//用户持有数量大于等于消耗数量
                        booleans.add(Boolean.TRUE);
                    } else {
                        booleans.add(Boolean.FALSE);
                    }
                }

                expendList.add(ecologyCastExpendVO);
                ecologyCastWayVO.setExpendList(expendList);
            }
            if (booleans.contains(Boolean.FALSE)) {
                ecologyCastWayVO.setType(Boolean.FALSE);
            } else {
                if (ecologyCastDetails.getUpperLimit() > 0) {
                    ecologyCastWayVO.setType(Boolean.TRUE);
                }
            }
            ecologyCastWayVOList.add(ecologyCastWayVO);
        }

        if (filterIncomeListDao.checkIsFilterAccount(digitalCollectionDao.getById(ecologyCastConf.getCollectionId()).getUserCreatorId(), user.getId())
                || filterIncomeListDao.checkListIsFilterAccount(Arrays.asList(6L, 7L, 131L, 145L), user.getId())) {
            for (EcologyCastWayVO ecologyCastWayVO : ecologyCastWayVOList) {
                ecologyCastWayVO.setType(Boolean.TRUE);
            }
        }


        return ecologyCastWayVOList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void expend(Long id, Integer count, UserInfo user, Long wayId) throws GlobalException {
        EcologyCastConf ecologyCastConf = ecologyCastConfDao.getById(id);
        Assert.notNull(ecologyCastConf, () -> new GlobalRunTimeException("生态铸造配置不存在"));
        Assert.isTrue(ecologyCastConf.getStatus(), () -> new GlobalRunTimeException("生态铸造配置已下架"));

        EcologyCastWayConf ecologyCastWayConf = ecologyCastWayConfDao.getById(wayId);
        Assert.notNull(ecologyCastWayConf, () -> new GlobalRunTimeException("生态铸造方式配置不存在"));
        Assert.isTrue(ecologyCastWayConf.getStatus(), () -> new GlobalRunTimeException("生态铸造方式配置已下架"));
        Assert.isTrue(ecologyCastWayConf.getEcologyCastConfId().equals(id), () -> new GlobalRunTimeException("铸造方式不属于该生态铸造配置"));
        EcologyCastDetailsVO ecologyCastDetails = ecologyCastConfDao.getProductDetailsById(id);
        Assert.notNull(ecologyCastDetails, () -> new GlobalRunTimeException("生态铸造商品不存在"));
        List<EcologyCastExpendConf> list = ecologyCastExpendConfDao.getListByEcologyCastWayConfId(wayId);


        UserEcologyCastRecordsDetails userEcologyCastRecordsDetails = new UserEcologyCastRecordsDetails();
        userEcologyCastRecordsDetails.setUserId(user.getId());
        userEcologyCastRecordsDetails.setCollectionId(ecologyCastConf.getCollectionId());
        userEcologyCastRecordsDetails.setEcologyCastConfId(ecologyCastConf.getId());
        userEcologyCastRecordsDetails.setCollectionName(ecologyCastConf.getCollectionName());
        userEcologyCastRecordsDetails.setCastCount(count);
        userEcologyCastRecordsDetails.setEcologyCastWayConfId(wayId);
        userEcologyCastRecordsDetails.insert();

        //如果铸造的藏品 用户不是这个dao的市值账号
        // 1.则需要判断是否达到熔炼上限
        // 2.只有熔炼了才能铸造

        //判断用户是否是dao下的市值账号
        if (!filterIncomeListDao.checkIsFilterAccount(digitalCollectionDao.getById(ecologyCastConf.getCollectionId()).getUserCreatorId(), user.getId())
                //判断用户是否是市值账号
                && !filterIncomeListDao.checkListIsFilterAccount(Arrays.asList(6L, 7L, 131L, 145L), user.getId())
        ) {
            Assert.isTrue(userEcologyHatchRecordsDao.getNewCountByStatusAndUserIdAndCollectionId(user.getId(), ecologyCastConf.getCollectionId()) > 0
                    , () -> new GlobalRunTimeException("只有参与此藏品熔炼才能铸造"));
            //铸造上限
            UserEcologyCastUpperLimit userEcologyCastUpperLimit = userEcologyCastUpperLimitDao.getOneByUserIdAndCollectionId(user.getId(), ecologyCastConf.getCollectionId());
            int usableCount = ObjectUtil.isNull(userEcologyCastUpperLimit) ? 0 : userEcologyCastUpperLimit.getUsableCount();
            Assert.isTrue(usableCount >= count.intValue(), () -> new GlobalRunTimeException("铸造数量超过上限"));
            //减去铸造上限
            userEcologyCastUpperLimitService.subCountByUserIdAndCollectionId(
                    user.getId(), ecologyCastConf.getCollectionId(), count, UserEcologyCastUpperLimitDetailsTypeEnum.CAST,
                    StrUtil.format("铸造:{}", ecologyCastConf.getCollectionName()), userEcologyCastRecordsDetails.getId());
        }

        for (EcologyCastExpendConf ecologyCastExpendConf : list) {
            //生态积分
            if (ecologyCastExpendConf.getExpendType() == EcologyExpendType.ECOLOGY_POINTS) {
                UserEcologyPoints userEcologyPoints = userEcologyPointsService.getOneByUserId(user.getId());

                BigDecimal sumCount = ecologyCastExpendConf.getExpendCount().multiply(Convert.toBigDecimal(count));
                //用户余额 大于 所需数量
                Assert.isTrue(NumberUtil.isGreaterOrEqual(userEcologyPoints.getAmount(), sumCount), () -> new GlobalRunTimeException("生态燃料不足"));
                //扣除燃料
                Assert.isTrue(userEcologyPointsService.subAmount(user.getId(), sumCount, EcologyPointsEnum.CAST, StrUtil.EMPTY), () -> new GlobalRunTimeException("铸造失败,请稍后重试!"));
                //添加记录
                UserEcologyCastRecords userEcologyCastRecords = new UserEcologyCastRecords();
                userEcologyCastRecords.setRecordsId(userEcologyCastRecordsDetails.getId());
                userEcologyCastRecords.setUserId(user.getId());
                userEcologyCastRecords.setEcologyCastConfId(ecologyCastConf.getId());
                userEcologyCastRecords.setEcologyCastExpendConfId(ecologyCastExpendConf.getId());
                userEcologyCastRecords.setExpendType(ecologyCastExpendConf.getExpendType());
                userEcologyCastRecords.setExpendCount(sumCount);
                userEcologyCastRecords.setExpendName(ecologyCastExpendConf.getExpendType().getDescription());
                userEcologyCastRecords.setExpendImage(staticDataDao.getByType("ecology_points_image").getValue());
                userEcologyCastRecords.setCollectionName(ecologyCastConf.getCollectionName());
                userEcologyCastRecords.setCastCount(count);
                userEcologyCastRecords.setEcologyCastWayConfId(wayId);
                userEcologyCastRecords.insert();
            }
            //权益道具
            if (ecologyCastExpendConf.getExpendType() == EcologyExpendType.EQUITY_PROPS) {
                Integer havingCount = userEquityPropsService.getHavingCountByUserId(ecologyCastExpendConf.getExpendId(), user.getId());
                Integer sumCount = Convert.toInt(ecologyCastExpendConf.getExpendCount().multiply(Convert.toBigDecimal(count)));
                Assert.isTrue(havingCount.intValue() >= sumCount.intValue(), () -> new GlobalRunTimeException("权益道具持有量不足"));

                List<UserEquityProps> userEquityPropsList = userEquityPropsService.getHavingListByUserIdAndEquityPropsIdAndLimit(user.getId(), ecologyCastExpendConf.getExpendId(), sumCount);
                Assert.isTrue(userEquityPropsList.size() == sumCount, () -> new GlobalRunTimeException("铸造失败,请稍后重试!"));

                Assert.isTrue(
                        userEquityPropsService.normalToconsumeByIds(userEquityPropsList, user.getId(), ecologyCastConf.getProductName(), ecologyCastConf.getId(), UserEquityPropsUseTypeEnum.ECOLOGY_CAST)
                        , () -> new GlobalRunTimeException("铸造失败,请稍后重试!"));

                //添加记录
                UserEcologyCastRecords userEcologyCastRecords = new UserEcologyCastRecords();
                userEcologyCastRecords.setRecordsId(userEcologyCastRecordsDetails.getId());
                userEcologyCastRecords.setUserId(user.getId());
                userEcologyCastRecords.setEcologyCastConfId(ecologyCastConf.getId());
                userEcologyCastRecords.setEcologyCastExpendConfId(ecologyCastExpendConf.getId());
                userEcologyCastRecords.setExpendType(ecologyCastExpendConf.getExpendType());
                userEcologyCastRecords.setExpendCount(Convert.toBigDecimal(sumCount));
                userEcologyCastRecords.setExpendName(ecologyCastExpendConf.getExpendName());
                userEcologyCastRecords.setExpendImage(ecologyCastExpendConf.getExpendImage());
                userEcologyCastRecords.setExpendId(ecologyCastExpendConf.getExpendId());
                userEcologyCastRecords.setCollectionName(ecologyCastConf.getCollectionName());
                userEcologyCastRecords.setCastCount(count);
                userEcologyCastRecords.setEcologyCastWayConfId(wayId);
                userEcologyCastRecords.insert();

            }
            //积分
            if (ecologyCastExpendConf.getExpendType() == EcologyExpendType.ECOLOGY_MARK) {
                EcologyPoints ecologyPoints = ecologyPointsService.getById(ecologyCastExpendConf.getExpendId());
                Assert.notNull(ecologyPoints,()-> new GlobalRunTimeException("积分不存在"));
                UserEcologyPointsWallet userEcologyPointsWallet = userEcologyPointsWalletService.getOneByUserIdAndPointId(ecologyCastExpendConf.getExpendId(),user.getId());
                BigDecimal amount = BigDecimal.ZERO;
                if (Objects.nonNull(userEcologyPointsWallet)) {
                    amount = userEcologyPointsWallet.getAmount();
                }
                BigDecimal sumCount = ecologyCastExpendConf.getExpendCount().multiply(Convert.toBigDecimal(count));
                //用户余额 大于 所需数量
                Assert.isTrue(NumberUtil.isGreaterOrEqual(amount, sumCount), () -> new GlobalRunTimeException("积分不足"));
                //扣除积分
                Assert.isTrue(userEcologyPointsWalletService.adjustAmount(user.getId(),ecologyCastExpendConf.getExpendId(),ecologyCastExpendConf.getExpendName(), sumCount, EcologyPointsWalletEnum.CAST, StrUtil.EMPTY), () -> new GlobalRunTimeException("铸造失败,请稍后重试!"));
                //添加记录
                //添加记录
                UserEcologyCastRecords userEcologyCastRecords = new UserEcologyCastRecords();
                userEcologyCastRecords.setRecordsId(userEcologyCastRecordsDetails.getId());
                userEcologyCastRecords.setUserId(user.getId());
                userEcologyCastRecords.setEcologyCastConfId(ecologyCastConf.getId());
                userEcologyCastRecords.setEcologyCastExpendConfId(ecologyCastExpendConf.getId());
                userEcologyCastRecords.setExpendType(ecologyCastExpendConf.getExpendType());
                userEcologyCastRecords.setExpendCount(Convert.toBigDecimal(sumCount));
                userEcologyCastRecords.setExpendName(ecologyCastExpendConf.getExpendName());
                userEcologyCastRecords.setExpendImage(ecologyCastExpendConf.getExpendImage());
                userEcologyCastRecords.setExpendId(ecologyCastExpendConf.getExpendId());
                userEcologyCastRecords.setCollectionName(ecologyCastConf.getCollectionName());
                userEcologyCastRecords.setCastCount(count);
                userEcologyCastRecords.setEcologyCastWayConfId(wayId);
                userEcologyCastRecords.insert();
            }


        }
        DigitalCollectionProductInfo prduct = digitalCollectionProductInfoDao.getById(ecologyCastDetails.getProductId());

        //铸造上链费
        if (prduct.getGasConf()) {
            GasConsumeDTO gasConsume = getGasConsumeDTO(user, prduct);
            orderGasService.gasConsume(gasConsume);
        }

        boolean isOpen = false;
        Long boxId = null;
        String boxTitle = null;
        String boxImage = null;
        Long collectionId = null;
        for (int i = 0; i < count; i++) {
            switch (prduct.getTypeClassify()) {
                case COLLECTION:
                    collectionId = prduct.getRelationId();
                    isOpen = true;
                    Assert.isTrue(productStockService.deductStock(prduct.getId(), prduct.getRelationId(), 1, user.getId(), CommodityType.ECOLOGY_COMMODITY), () -> new GlobalRunTimeException("库存不足"));
                    break;
                case BLIND_BOX:
                    BoxItem boxItem = boxItemService.openBox(prduct.getId(), prduct.getRelationId());
                    collectionId = boxItem.getCollectionId();
                    Assert.isTrue(productStockService.subItemStock(prduct.getId(), prduct.getRelationId(), boxItem.getId(), 1, user.getId(), CommodityType.ECOLOGY_COMMODITY), () -> new GlobalRunTimeException("库存不足"));
                    BoxProduct boxProduct = boxProductDao.getById(prduct.getRelationId());
                    boxId = boxProduct.getId();
                    boxTitle = boxProduct.getFirstTitle();
                    boxImage = prduct.getCreationContent();
                    isOpen = false;
                    break;
            }
            DigitalCollection digitalCollection = digitalCollectionDao.getById(collectionId);
            UserCollection userCollection = userCollectionService.addCollection(user.getId(), null, digitalCollection.getId(), IdUtil.getSnowflakeNextIdStr(), digitalCollection.getCreationContent(), digitalCollection.getLevel(), digitalCollection.getFirstTitle(),
                    digitalCollection.getUserCreatorId(), ReceivedCollectionType.ECOLOGY_HATCH, boxId, boxTitle, boxImage, isOpen, prduct.getId(), 0L, 0L, BigDecimal.ZERO, 0, null, null, AddCollectionEnum.STAIR, null, null, false);

            //藏品流转表记录
            CollectionCirculatingRecord collectionCirculatingRecord = new CollectionCirculatingRecord();
            collectionCirculatingRecord.setUserId(user.getId());
            collectionCirculatingRecord.setCollectionId(digitalCollection.getId());
            collectionCirculatingRecord.setCommodityType(CommodityType.ECOLOGY_COMMODITY);
            collectionCirculatingRecord.setTypeClassify(prduct.getTypeClassify());
            collectionCirculatingRecord.setReceivedCollectionType(ReceivedCollectionType.ECOLOGY_HATCH);
            collectionCirculatingRecord.setToUserCollection(userCollection.getId());
            collectionCirculatingRecord.setOrderId(0L);
            collectionCirculatingRecord.insert();
        }

    }

    private static GasConsumeDTO getGasConsumeDTO(UserInfo user, DigitalCollectionProductInfo prduct) {
        GasConsumeDTO gasConsume=new GasConsumeDTO();
        gasConsume.setConsumeCost(prduct.getConsumeCost());
        gasConsume.setUserId(user.getId());
        gasConsume.setGasConsumeType(prduct.getConsumeType());
        gasConsume.setWalletDetailType(WalletDetailTypeEnum.GAS_ECOLOGY_CAST_EXPEND);
        gasConsume.setProductId(prduct.getId());
        gasConsume.setCollectionId(prduct.getRelationId());
        gasConsume.setOrderGasType(OrderGasTypeEnum.GAS_ECOLOGY_CAST_EXPEND);
        return gasConsume;
    }

    @Override
    public Page<ExpendEcologyCastRecordsVO> expendRecords(UserInfo user, Integer pageNo, Integer pageSize) {
        return userEcologyCastRecordsDao.expendRecords(user.getId(), pageNo, pageSize);
    }

    @Override
    public Page<EcologyExpenditureRecordVO> ecologyExpenditureRecord(UserInfo user, Integer pageNo, Integer pageSize) {
        //生态燃料图片
        String ecologyPointsImage = staticDataDao.getByType("ecology_points_image").getValue();
        Page<EcologyExpenditureRecordVO> page = userEcologyExpenditureRecordDao.ecologyExpenditureRecord(user.getId(), pageNo, pageSize);
        for (EcologyExpenditureRecordVO record : page.getRecords()) {
            if (record.getType() == UserEcologyExpenditureTypeEnum.ECOLOGY_POINTS) {
                record.setLinkImage(ecologyPointsImage);
            }
        }
        return page;
    }

    @Override
    public Page<UserEcologyDetailVO> userEcologyDetail(UserInfo user, Integer pageNo, Integer pageSize) {
        String ecologyPointsImage = staticDataDao.getByType("ecology_points_image").getValue();
        Page<UserEcologyDetailVO> page = userEcologyExpenditureRecordDao.userEcologyDetail(user.getId(), pageNo, pageSize);
        for (UserEcologyDetailVO detail : page.getRecords()) {
            detail.setImage(ecologyPointsImage);
            detail.setTypeName(detail.getType().getDescription());
            if (StrUtil.isBlank(detail.getRemark())) {
                detail.setRemark(detail.getTypeName());
            }
        }
        return page;
    }

    @Override
    public Page<UserEcologyExpenditureRecordPageVO> userEcologyExpenditureRecordPage(UserInfo user, UserEcologyExpenditureTypeEnum type, Integer pageNo, Integer pageSize,Long linkId) {
        return userEcologyExpenditureRecordDao.userEcologyExpenditureRecordPage(user.getId(), ObjectUtil.isNull(type) ? 1 : type.getCode(), pageNo, pageSize,linkId);
    }

    @Override
    public Page<EcologyExpenditureRecordVO> userEcologyExpenditureRecordDetailsPage(UserInfo user, UserEcologyExpenditureTypeEnum type, Integer dateTime, Integer pageNo, Integer pageSize,Long linkId) {
        return userEcologyExpenditureRecordDao.userEcologyExpenditureRecordDetailsPage(user.getId(), ObjectUtil.isNull(type) ? 1 : type.getCode(), dateTime, pageNo, pageSize,linkId);
    }

    @Override
    public Page<UserExpendRecordsPageVO> expendRecordsPage(UserInfo user, Integer pageNo, Integer pageSize,Long userCreatorId) {
        return userEcologyCastRecordsDetailsDao.expendRecordsPage(user.getId(), pageNo, pageSize,userCreatorId);
    }

    @Override
    public List<ExpendEcologyCastRecordsVO> expendRecordsDetails(UserInfo user, Long id) {
        return userEcologyCastRecordsDao.expendRecordsDetails(user.getId(), id);
    }

    @Override
    public Page<UserEcologyCastUpperLimitDetailsVO> userEcologyCastUpperLimitDetails(UserInfo user, Long id, Integer pageNo, Integer pageSize) {
        EcologyCastConf ecologyCastConf = ecologyCastConfDao.getById(id);
        Assert.notNull(ecologyCastConf, () -> new GlobalRunTimeException("生态铸造配置不存在"));

        return userEcologyCastUpperLimitDetailsDao.getUserEcologyCastUpperLimitDetails(user.getId(), ecologyCastConf.getCollectionId(), pageNo, pageSize);
    }

}
